-
Notifications
You must be signed in to change notification settings - Fork 469
Add support for host specialization with unencrypted payload #11302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new host API endpoint for assigning without encrypted payload to improve memory efficiency. The change introduces a new unencrypted assignment endpoint alongside the existing encrypted one, which will be useful for ATOL scenarios.
Key Changes
- Added a new assignment endpoint that accepts unencrypted payload
- Refactored existing assignment logic into a shared private method
- Created a new model to wrap the unencrypted assignment context
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
StartupContextProvider.cs | Added new overload method to handle unencrypted HostAssignmentContext |
FunctionsWorkerContainerAssignmentContext.cs | New model class to wrap assignment context for the new API |
InstanceController.cs | Added new assignment endpoint and refactored shared logic into private method |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
src/WebJobs.Script.WebHost/Models/FunctionsWorkerContainerAssignmentContext.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of adding a new endpoint entirely, can we update EncryptedHostAssignmentContext
as follows:
- rename to
HostAssignmentRequest
- add properties as follows:
public class HostAssignmentRequest
{
[JsonProperty("encryptedContext")]
public string EncryptedContext { get; set; }
[JsonProperty("context")]
public HostAssignmentContext Context { get; set; }
}
Now callers can choose to supply encrypted or not based on what JSON payload they send. The implementation will then check which of the two properties is not-null and use that.
Hi, Thats a valid suggestion. But, that will break backward compatibility and makes it very difficult to deploy. We would need to change current flow of assignment in Antares outside ATOL. We would have to check which hostversion is supporting which endpoint and send object accordingly. With new endpoint, we can remove old endpoint once we move to endpoint entirely. In legion as well, we have seperate endppints for encrypted and unencypted payload to make it easier for maintenance |
@manikantanallagatla can you expand more on how my proposal limits maintenance? I am not quite understanding your point.
How so? One API will serve both formats of JSON. The existing encrypted, or the new unencrypted. The caller can send either of the two formats. {
"encryptedContext": "< some encrypted string >"
} or {
"context": {
"siteName": "MySiteName", // and the rest of the object
}
}
And with my proposal we can remove the support for What this boils down to, is ATOL can call |
Oh got it. There is a HostAssignmentContext inside HostAssignmentRequest. I missed that. Apologies. We can make it a single request with this. I will give it a try. Thanks @jviau |
4aeaa40
to
9e46fdd
Compare
@manikantanallagatla I see you re-requested my review, but I don't see the changes we discussed. There are still 2 separate APIs and encrypted/unencrypted models are not combined into the same top-level type. Are these changes still coming? |
@jviau just for my curiosity, why do we want to hack into existing api and break the request model object structure from current flow and combining multiple properties where only one is used at any given time, instead of keeping the cleaner segregation with different APIs and their models, and not breaking/modifying the current API on the way. @manikantanallagatla let's ensure any changes here are aligned by everyone and thought through, because I think we might be making some changes on Legion Platform side or Go Server code to call these APIs while maintaining backward compatibility. Might have to change all those if we have to retrofit new behavior into existing API without breaking the current flows. |
@jviau , I merged the APIs into 1 API and requested review. Then when I discussed with Bala, we wanted two separate APIs so that it is cleaner. So, I again reverted that commit of merging into 1 API. Anyways I will start a thread in teams to have a conclusion on 1 API vs 2 APIs. |
I don't see this as a hack at all. It doesn't break anything. We are effectively turning the existing JSON payload into a "One-Of" structure. It is either the encrypted payload or the unencrypted payload, and the existing API will determine what assign flow to use based on the shape of the JSON input. We can add validation in the API handler to assert only one can be set at a time. I do not think having an Existing callers. This is the same as today, and it will be the same after my suggested changes. There is no change for these callers. POST "admin/instance/assign"
{
"encryptedContext": "< encrypted context >"
} NEW callers wanting unencrypted assign: POST "admin/instance/assign"
{
"context": {
// unencrypted host assignment context
}
} Additional scenario which will result in an HTTP 400. Callers will not be allowed to provide both encrypted and unencrypted context. POST "admin/instance/assign"
{
"encryptedContext": "< encrypted context >",
"context": {
// unencrypted host assignment context
}
} |
src/WebJobs.Script.WebHost/Models/FunctionsWorkerContainerAssignmentContext.cs
Outdated
Show resolved
Hide resolved
src/WebJobs.Script.WebHost/Models/FunctionsWorkerContainerAssignmentContext.cs
Outdated
Show resolved
Hide resolved
9e46fdd
to
4c83a23
Compare
test/WebJobs.Script.Tests.Integration/Host/StandbyManager/StandbyManagerE2ETests_Linux.cs
Show resolved
Hide resolved
|
||
var encryptedAssignmentContext = JsonConvert.DeserializeObject<EncryptedHostAssignmentContext>(startContext); | ||
var assignmentContext = _startupContextProvider.SetContext(encryptedAssignmentContext); | ||
var hostAssignmentRequest = JsonConvert.DeserializeObject<HostAssignmentRequest>(startContext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above TryGetStartContextOrNullAsync virtual call has a different implementation on Legion and Atlas. This same hosted service code is running on each SKU. Just want to confirm that there isn't any breaking format change here - the persisted assignment context is always encrypted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried for legion changes by giving encrypted and unencrypted payload for controller and it is working fine. Means encrypted path of controller which is existing is working fine.
Any way to test this storage path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just pointing out how the system behaves. Likely things are OK, since up to this point only encrypted was supported, and your new deserialization supports both old and new formats. I'm just this out so you can think about this and ensure no breaks. Bala knows the context storage logic the best so you might have him sign off on this as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Will check with Bala
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storage one is only used in CV1 on ACI path(Atlas). We are not changing anything wrt encryption payload. So, storage path should not be affected by this repo. They should continue the encrypted payload and no changes needed.
For legion path, technically it should work as we are storing the volume in https://msazure.visualstudio.com/One/_git/AAPT-Antares-Functions-Docker?path=/images/flexconsumption/components/appserver/cv2/pkg/instance/instance.go&version=GBdev&line=76&lineEnd=77&lineStartColumn=1&lineEndColumn=1&lineStyle=plain&_a=contents
I will check legion for both encrypted and unencrypted path
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have tested both paths and they are working fine.
src/WebJobs.Script.WebHost/Security/Authentication/Jwt/ScriptJwtBearerExtensions.cs
Show resolved
Hide resolved
test/WebJobs.Script.Tests.Integration/Host/StandbyManager/StandbyManagerE2ETests_Linux.cs
Outdated
Show resolved
Hide resolved
src/WebJobs.Script.WebHost/Security/Authentication/Jwt/ScriptJwtBearerExtensions.cs
Outdated
Show resolved
Hide resolved
src/WebJobs.Script.WebHost/Security/Authentication/SecurityConstants.cs
Outdated
Show resolved
Hide resolved
var hostAssignmentContext = JsonConvert.DeserializeObject<HostAssignmentContext>(decryptedContext); | ||
var hostAssignmentContext = hostAssignmentRequest.AssignmentContext; | ||
|
||
if (!string.IsNullOrEmpty(hostAssignmentRequest.EncryptedContext)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if you shouldn't add a clause hostAssignmentContext == null to this if, making it clear that only one of these should ever be specified. As opposed to the precedence handling you have here, where both can be specified, but encrypted wins.
I realize in the controller method you do validation, but there's another path where this method is called, where the request is pulled from storage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure how the storage path works. But shall we move the handling that only one needs to be specified here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are sure storage account path only takes encrypted payload, we can have method overloading for SetContext method. One which takes encrypted payload and other that takes unencrypted payload
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The storage path where context is pulled from storage MUST be encrypted since data must be encrypted at rest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The storage path where context is pulled from storage MUST be encrypted since data must be encrypted at rest.
This is a bit besides the point, but is this the customer's storage account? The encrypted at rest requirement here would be the storage account itself satisfying that. All data in a storage account is already "encrypted at rest": https://learn.microsoft.com/en-us/azure/storage/common/storage-service-encryption.
The only time we, the Functions Host team, would have an "encrypted at rest" requirement is if we were offering some storage solution which did not already have encrypted-at-rest features.
But back to the main point: I agree that if we expect storage scenario to always have client-side encryption (which is what this is), then we should assert that as necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storage is only used in CV1 on ACI path. We are not touching that path. So, storage wise, no change with this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think no changes are needed for storage and current validations in StartupContextProvider.cs seems fine
src/WebJobs.Script.WebHost/ContainerManagement/LinuxContainerInitializationHostedService.cs
Show resolved
Hide resolved
} | ||
else | ||
{ | ||
if (!User.HasClaim(SecurityConstants.AssignUnencryptedClaimType, "true")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this method do case sensitive check? Would that be a concern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are adding the string in ScriptJwtBearerExtensions and checking here. So, we dont need case sensitive check right
Issue describing the changes in this PR
Current assign endpoint takes a encrypted payload for specializing. This is not memory efficient. Adding new API for taking the specialization unencrypted. This will be usedul in ATOL as well
Pull request checklist
IMPORTANT: Currently, changes must be backported to the
in-proc
branch to be included in Core Tools and non-Flex deployments.in-proc
branch is not requiredrelease_notes.md